home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Sample Code / Sprocket / Lib / AppleEventHandling.cp next >
Encoding:
Text File  |  1994-12-15  |  9.6 KB  |  332 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        AppleEventHandling.cp
  3.  
  4.     Contains:    Minimalist support for the required and Display Manager AppleEvents
  5.                 We also support openning and printing “LetterSpec” documents for AOCE.
  6.                 
  7.                 To really support AppleScript™, we’ll need to do ALOT more work in here.
  8.  
  9.     Written by: Dave Falkenburg
  10.  
  11.     Copyright:    © 1993-94 by Dave Falkenburg, all rights reserved.
  12.  
  13.     Change History (most recent first):
  14.      
  15.          <7>    12/15/94    DRF        Added ChooseApplicationAsAETarget.
  16.          <6>    11/23/94    DRF        InstallAppleEventHandlers is now called InitAppleEventRoutines.
  17.                                     Also added a useful global: gThisProcessDesc for self targetting
  18.                                     of AppleEvents.
  19.          <5>    11/16/94    DRF        Add StandardAEIdleProc for people who like using AESend with
  20.                                     kAEWaitReply.
  21.          <4>    11/12/94    DRF        Removed extra #include.
  22.          <3>     9/27/94    DRF         AppLib.h is now Sprocket.h
  23.          <2>      9/4/94    DRF        Added stub Text Services AppleEvent handlers.
  24.  */
  25.  
  26. #include "Sprocket.h"
  27.  
  28. #include <AppleEvents.h>
  29. #include <Errors.h>
  30. #include <Displays.h>            //    for Display Manager AppleEvent constants
  31. #include <OCEStandardMail.h>    //    for LetterSpec
  32.  
  33. #if    qInlineInputAware
  34. #include <TextServices.h>
  35. #endif
  36.  
  37. #include "AppleEventHandling.h"
  38.  
  39. static pascal Boolean StandardAEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn);
  40.     
  41.  
  42. AEDesc        gThisProcessDesc;
  43.  
  44. void
  45. InitAppleEventRoutines(void)
  46.     {
  47.     ProcessSerialNumber    thisProcess;
  48.  
  49.     //    Create useful AE Targets for our aplication
  50.  
  51.     //    By building the target in this fashion, we get the best performance
  52.     //    out of the AppleEvent manager because it can call our event handlers
  53.     //    inline.
  54.  
  55.     thisProcess.highLongOfPSN     = 0;
  56.     thisProcess.lowLongOfPSN     = kCurrentProcess;
  57.     (void) AECreateDesc(typeProcessSerialNumber,(Ptr)&thisProcess, sizeof(ProcessSerialNumber),&gThisProcessDesc);
  58.  
  59.  
  60.     //    It’s probably more efficient to use a table to install these handlers…
  61.     
  62.     (void) AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,NewAEEventHandlerProc(HandleOpenApplication),0,false);
  63.     (void) AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,NewAEEventHandlerProc(HandleOpenDocuments),0,false);
  64.     (void) AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,NewAEEventHandlerProc(HandlePrintDocuments),0,false);
  65.     (void) AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,NewAEEventHandlerProc(HandleQuitApplication),0,false);
  66.  
  67.     //    regardless of whether or not we have the display manager, go ahead and register an AppleEvent handler
  68.     (void) AEInstallEventHandler(kCoreEventClass,kAESystemConfigNotice,NewAEEventHandlerProc(HandleSystemConfigNotice),0,false);
  69.  
  70. #if    qInlineInputAware
  71.     if (gHasTextServices)
  72.         {
  73.         (void) AEInstallEventHandler(kTextServiceClass,kUpdateActiveInputArea,NewAEEventHandlerProc(HandleTextServicesUpdateActiveInputArea),0,false);
  74.         (void) AEInstallEventHandler(kTextServiceClass,kPos2Offset,NewAEEventHandlerProc(HandleTextServicesPos2Offset),0,false);
  75.         (void) AEInstallEventHandler(kTextServiceClass,kOffset2Pos,NewAEEventHandlerProc(HandleTextServicesOffset2Pos),0,false);
  76.         //    we don’t need to handle <kTextServiceClass,kShowHideInputWindow> events
  77.         }
  78. #endif
  79.     }
  80.  
  81.  
  82. OSErr
  83. CheckAppleEventForMissingParams(AppleEvent *theAppleEvent)
  84.     {
  85.     DescType    returnedType;
  86.     Size        actualSize;
  87.     OSErr        err;
  88.     
  89.     err = AEGetAttributePtr(theAppleEvent,keyMissedKeywordAttr,typeWildCard,
  90.                             &returnedType,nil,0,&actualSize);
  91.     
  92.     if (err == errAEDescNotFound)        //    If we couldn’t find the error attribute
  93.         return noErr;                    //        everything is ok, return noErr
  94.     
  95.     if (err == noErr)                    //    We found an error attribute, so
  96.         return errAEEventNotHandled;    //        tell the client we ignored the event
  97.  
  98.     return err;                            //    Something else happened, return it
  99.     }
  100.  
  101.  
  102. OSErr
  103. ChooseApplicationAsAETarget(AEAddressDesc *targetDesc, StringPtr prompt)
  104.     {
  105.     PortInfoRec        thePortInfo;
  106.     LocationNameRec    theLocation;
  107.     TargetID        theTargetID;
  108.     OSErr            err;
  109.  
  110.     err = PPCBrowser(prompt, "\p", false, &theLocation, &thePortInfo, (PPCFilterUPP) NULL, "\p");
  111.     if (err == noErr)
  112.         {
  113.         theTargetID.name = thePortInfo.name;
  114.         theTargetID.location = theLocation;
  115.  
  116.         err = AECreateDesc(typeTargetID,&theTargetID,sizeof(theTargetID),targetDesc);
  117.         }
  118.  
  119.     return err;
  120.     }
  121.  
  122.  
  123. AEIdleUPP        StandardAEIdleUPP = NewAEIdleProc(StandardAEIdleProc);
  124.  
  125. static pascal Boolean
  126. StandardAEIdleProc(EventRecord *theEvent, long * /* sleepTime */, RgnHandle * /* mouseRgn */)
  127.     {
  128.     HandleEvent(theEvent);            //    First, always hand event off to our event handling code
  129.     return false;                    
  130.     }
  131.  
  132.  
  133. OSErr
  134. ForEachDocumentInList(AEDescList documentList,EachDocumentProcPtr documentProc,void * documentParam)
  135.     {
  136.     long                documentCount,documentIndex;
  137.     DescType            returnedType;
  138.     Size                actualSize;
  139.     LetterDescriptor    theLetterDesc;
  140.     AEKeyword            keyword;
  141.     OSErr                err;
  142.  
  143.     if ((err = AECountItems(&documentList,&documentCount)) != noErr)
  144.         return err;
  145.     
  146.     for (documentIndex=1; documentIndex <= documentCount; documentIndex++)
  147.         {
  148.         //    What kind of document is it?
  149.         if ((err = AESizeOfNthItem(&documentList,documentIndex,&returnedType,&actualSize)) != noErr)
  150.             return err;
  151.         
  152.         //    Is it an AOCE letter?
  153.         if (returnedType == typeLetterSpec)
  154.             {
  155.             //    It’s a letter
  156.             theLetterDesc.onDisk = false;
  157.             err = AEGetNthPtr(&documentList,documentIndex,typeLetterSpec,&keyword,&returnedType,
  158.                                 (Ptr) &theLetterDesc.u.mailboxSpec, sizeof(theLetterDesc.u.mailboxSpec),&actualSize);
  159.             }
  160.         else
  161.             {
  162.             //    It’s just a normal document file
  163.             theLetterDesc.onDisk = true;
  164.             err = AEGetNthPtr(&documentList,documentIndex,typeFSS,&keyword,&returnedType,
  165.                                 (Ptr) &theLetterDesc.u.fileSpec,sizeof(theLetterDesc.u.fileSpec),&actualSize);
  166.             }
  167.             
  168.         if (err == noErr)
  169.             (*documentProc)(&theLetterDesc,documentParam);
  170.         else
  171.             break;
  172.         }
  173.     
  174.     return    err;
  175.     }
  176.  
  177.     
  178. pascal OSErr
  179. HandleOpenApplication(AppleEvent *theAppleEvent,AppleEvent * /*reply*/,long /*refCon*/)
  180.     {
  181.     OSErr    err;
  182.     
  183.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  184.         return err;
  185.  
  186.     return(CreateNewDocument());
  187.     }
  188.  
  189.  
  190. pascal OSErr
  191. HandleOpenDocuments(AppleEvent *theAppleEvent,AppleEvent * /*reply*/,long /*refCon*/)
  192.     {
  193.     AEDescList            documentList;
  194.     OSErr                err;
  195.     
  196.     if ((err = AEGetParamDesc(theAppleEvent,keyDirectObject,typeAEList,&documentList)) != noErr)
  197.         return err;
  198.  
  199.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  200.         return err;
  201.  
  202.     err = ForEachDocumentInList(documentList,&OpenDocument,nil);
  203.     (void) AEDisposeDesc(&documentList);
  204.     return err;
  205.     }
  206.  
  207.  
  208. pascal OSErr
  209. HandlePrintDocuments(AppleEvent *theAppleEvent,AppleEvent * /*reply*/,long /*refCon*/)
  210.     {
  211.     AEDescList            documentList;
  212. #if    qUseQuickDrawGX
  213.     AEDescList            desktopPrinterList;
  214.     FSSpec                thePrinterFSSpec;
  215.     Boolean                draggedToDesktopPrinter = false;
  216. #endif
  217.     OSErr                err;
  218.     
  219.     if ((err = AEGetParamDesc(theAppleEvent,keyDirectObject,typeAEList,&documentList)) != noErr)
  220.         return err;
  221.  
  222. #if    qUseQuickDrawGX
  223.     if (noErr == AEGetAttributeDesc(theAppleEvent,keyOptionalKeywordAttr,typeAEList,&desktopPrinterList))
  224.         draggedToDesktopPrinter = true;
  225. #endif
  226.  
  227.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  228.         return err;
  229.  
  230. #if    qUseQuickDrawGX
  231.     if (draggedToDesktopPrinter)
  232.         {
  233.         DescType            returnedType;
  234.         Size                actualSize;
  235.         AEKeyword            keyword;
  236.  
  237.         err = AEGetNthPtr(&desktopPrinterList,1,typeFSS,&keyword,&returnedType,
  238.                             (Ptr) &thePrinterFSSpec,sizeof(thePrinterFSSpec),&actualSize);
  239.  
  240.         (void) AEDisposeDesc(&desktopPrinterList);
  241.         }
  242.     err = ForEachDocumentInList(documentList,&PrintDocument,draggedToDesktopPrinter ? &thePrinterFSSpec : NULL);
  243.     (void) AEDisposeDesc(&documentList);
  244. #else
  245.     err = ForEachDocumentInList(documentList,&PrintDocument,nil);
  246. #endif
  247.  
  248.     return err;
  249.     }
  250.  
  251.  
  252. pascal OSErr
  253. HandleQuitApplication(AppleEvent *theAppleEvent,AppleEvent * /* reply */,long /* refCon */)
  254.     {
  255.     OSErr    err;
  256.     
  257.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  258.         return err;
  259.  
  260.     gDone = QuitApplication();
  261.     
  262.     if (gDone)
  263.         return noErr;
  264.     else
  265.         return userCanceledErr;
  266.     }
  267.  
  268.  
  269. ////////////////////////////////////////////////////////////////////////
  270. //
  271. //    Display Manager Suite is “Under Construction”
  272. //
  273. //    To Do: Check ERS for Display Manager events
  274.  
  275. pascal OSErr
  276. HandleSystemConfigNotice(AppleEvent *theAppleEvent,AppleEvent * /* reply */,long /* refCon */)
  277.     {
  278.     AEDescList    displayList;
  279.     long        displayCount,displayIndex;
  280.     OSErr        err;
  281.     
  282.     DebugStr((StringPtr) "\pGot a Display Manager Event!");
  283.     
  284.     if ((err = AEGetParamDesc(theAppleEvent,kAEDisplayNotice,typeAEList,&displayList)) != noErr)
  285.         return err;
  286.     
  287.     if ((err = CheckAppleEventForMissingParams(theAppleEvent)) != noErr)
  288.         return err;
  289.     
  290.     if ((err = AECountItems(&displayList,&displayCount)) != noErr)
  291.         return err;
  292.  
  293.     for (displayIndex = 1; displayIndex<=displayCount; displayIndex++)
  294.         {
  295.         DebugStr((StringPtr) "\pProcessing a display");
  296.         
  297.         //    Gather up all the old and new display rectangles into an oldDeskRegion and a newDeskRegion
  298.         }
  299.  
  300.     //    run through all windows calling keeping all windows which were onscreen in the oldDeskRegion
  301.     //    onscreen in the new world. We should really be calling a method to do this so that windows
  302.     //    can individually deal with things in a manner which they can override.
  303.  
  304.  
  305.     return errAEEventNotHandled;    //    we really don’t handle this yet...
  306.     }
  307.  
  308. #if    qInlineInputAware
  309.  
  310. pascal OSErr
  311. HandleTextServicesUpdateActiveInputArea(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  312.     {
  313.     DebugStr("\pTextServicesUpdateActiveInputArea");
  314.     return errAEEventNotHandled;            //    we really don’t handle this yet...
  315.     }
  316.  
  317. pascal OSErr
  318. HandleTextServicesPos2Offset(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  319.     {
  320.     DebugStr("\pTextServicesPos2Offset");
  321.     return errAEEventNotHandled;            //    we really don’t handle this yet...
  322.     }
  323.     
  324. pascal OSErr
  325. HandleTextServicesOffset2Pos(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon)
  326.     {
  327.     DebugStr("\pTextServicesOffset2Pos");
  328.     return errAEEventNotHandled;            //    we really don’t handle this yet...
  329.     }
  330.  
  331. #endif
  332.